# # -*- conding:utf-8 -*-
# import json
# import os
# import sys
# import time
#
# from collections import namedtuple
# from ansible.executor.task_queue_manager import TaskQueueManager
# from ansible.inventory import Inventory
# from ansible.inventory.group import Group
# from ansible.inventory.host import Host
# from ansible.parsing.dataloader import DataLoader
# from ansible.playbook.play import Play
# from ansible.plugins.callback import CallbackBase
# from ansible.vars import VariableManager
# from ansible.executor.playbook_executor import PlaybookExecutor
#
#
# class ResultsCollector(CallbackBase):
#     def __init__(self, *args, **kwargs):
#         super(ResultsCollector, self).__init__(*args, **kwargs)
#         self.host_ok = {}
#         self.host_unreachable = {}
#         self.host_failed = {}
#
#     def v2_runner_on_unreachable(self, result):
#         self.host_unreachable[result._host.get_name()] = result
#
#     def v2_runner_on_ok(self, result, *args, **kwargs):
#         self.host_ok[result._host.get_name()] = result
#         # host = result._host
#         # vdata = json.dumps({host.name:result._result}, indent=4)
#         # print(vdata)
#
#     def v2_runner_on_failed(self, result, *args, **kwargs):
#         self.host_failed[result._host.get_name()] = result
#
#     def v2_runner_on_skipped(self, result):
#         self.state = 'skipped'
#         self.result = result._result
#
#     def v2_runner_on_no_hosts(self, task):
#         print('skipping: no hosts matched')
#
#     def v2_playbook_on_task_start(self, task, is_conditional):
#         print("TASK [%s]" % task.get_name().strip())
#
#     def v2_playbook_on_play_start(self, play):
#         name = play.get_name().strip()
#         if not name:
#             msg = "PLAY"
#         else:
#             msg = "PLAY [%s]" % name
#
#         print(msg)
#
#     def v2_playbook_on_stats(self, stats):
#         hosts = sorted(stats.processed.keys())
#         for h in hosts:
#             t = stats.summarize(h)
#
#             msg = "PLAY RECAP [%s] : %s %s %s %s %s" % (
#                 h,
#                 "ok: %s" % (t['ok']),
#                 "changed: %s" % (t['changed']),
#                 "unreachable: %s" % (t['unreachable']),
#                 "skipped: %s" % (t['skipped']),
#                 "failed: %s" % (t['failures']),
#             )
#         print(msg)
#
#
# class MyInventory(Inventory):
#     """
#     this is my ansible inventory object.
#     """
#
#     def __init__(self, resource, loader, variable_manager):
#         self.resource = resource
#         self.inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[])
#         self.gen_inventory()
#
#     def my_add_group(self, hosts, groupname, groupvars=None):
#         """
#         add hosts to a group
#         """
#         my_group = Group(name=groupname)
#
#         # if group variables exists, add them to group
#         if groupvars:
#             for key, value in groupvars.iteritems():
#                 my_group.set_variable(key, value)
#
#                 # add hosts to group
#         for host in hosts:
#             # set connection variables
#             hostname = host.get("hostname")
#             hostip = host.get('ip', hostname)
#             hostport = host.get("port")
#             username = host.get("username")
#             password = host.get("password")
#             ssh_key = host.get("ssh_key")
#             my_host = Host(name=hostname, port=hostport)
#             my_host.set_variable('ansible_ssh_host', hostip)
#             my_host.set_variable('ansible_ssh_port', hostport)
#             my_host.set_variable('ansible_ssh_user', username)
#             my_host.set_variable('ansible_ssh_pass', password)
#             my_host.set_variable('ansible_ssh_private_key_file', ssh_key)
#
#             # set other variables
#             for key, value in host.items():
#                 if key not in ["ip", "hostname", "port", "username", "password", "ssh_key"]:
#                     my_host.set_variable(key, value)
#                     # add to group
#             my_group.add_host(my_host)
#
#         self.inventory.add_group(my_group)
#
#     def gen_inventory(self):
#         """
#         add hosts to inventory.
#         """
#         if isinstance(self.resource, list):
#             self.my_add_group(self.resource, 'default_group')
#         elif isinstance(self.resource, dict):
#             for groupname, hosts_and_vars in self.resource.items():
#                 self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
#
#
# class MyRunner(object):
#     """
#     This is a General object for parallel execute modules.
#     """
#
#     def __init__(self, resource, *args, **kwargs):
#         self.resource = resource
#         self.inventory = None
#         self.variable_manager = None
#         self.loader = None
#         self.options = None
#         self.passwords = None
#         self.callback = None
#         self.__initializeData()
#         self.results_raw = {}
#
#     def __initializeData(self):
#         """
#         初始化ansible
#         """
#         Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'timeout', 'remote_user',
#                                          'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args',
#                                          'sftp_extra_args',
#                                          'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass',
#                                          'verbosity',
#                                          'check', 'listhosts', 'listtasks', 'listtags', 'syntax', 'tags'])
#
#         # initialize needed objects
#         self.variable_manager = VariableManager()
#         self.loader = DataLoader()
#         self.options = Options(connection='smart',
#                                module_path='/usr/local/python36/lib/python3.6/site-packages/ansible/modules', forks=100,
#                                timeout=10,
#                                remote_user='root', ask_pass=False, private_key_file=None, ssh_common_args=None,
#                                ssh_extra_args=None,
#                                sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None,
#                                become_user='root', ask_value_pass=False, verbosity=None, check=False, listhosts=False,
#                                listtasks=False, listtags=False, syntax=False, tags=[])
#
#         self.passwords = dict(sshpass=None, becomepass=None)
#         self.inventory = MyInventory(self.resource, self.loader, self.variable_manager).inventory
#         self.variable_manager.set_inventory(self.inventory)
#
#     def run(self, host_list, module_name, module_args):
#         play_source = dict(
#             name="Ansible Play",
#             hosts=host_list,
#             gather_facts='no',
#             tasks=[dict(action=dict(module=module_name, args=module_args))]
#         )
#         play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
#
#         tqm = None
#         self.callback = ResultsCollector()
#         try:
#             tqm = TaskQueueManager(
#                 inventory=self.inventory,
#                 variable_manager=self.variable_manager,
#                 loader=self.loader,
#                 options=self.options,
#                 passwords=self.passwords,
#             )
#             tqm._stdout_callback = self.callback
#             result = tqm.run(play)
#         finally:
#             if tqm is not None:
#                 tqm.cleanup()
#
#     def run_playbook(self, hosts, playbookfile, playbookvars):
#         """
#         run ansible palybook
#         """
#         try:
#             self.callback = ResultsCollector()
#             filenames = [playbookfile]  # playbook的路径
#             print('ymal file path:%s' % filenames)
#
#             extra_vars = playbookvars  # 额外的参数 sudoers.yml以及模板中的参数，它对应ansible-playbook test.yml --extra-vars "host='aa' name='cc' "
#             extra_vars['host'] = hosts
#             self.variable_manager.extra_vars = extra_vars
#             print('playbook 额外参数:%s' % self.variable_manager.extra_vars)
#
#             executor = PlaybookExecutor(
#                 playbooks=filenames, inventory=self.inventory, variable_manager=self.variable_manager,
#                 loader=self.loader,
#                 options=self.options, passwords=self.passwords,
#             )
#             executor._tqm._stdout_callback = self.callback
#             executor.run()
#         except Exception as e:
#             print("run_playbook:%s" % e)
#
#     def run_rule(self, hosts, playbookfile, playbooktag, playbookval):
#         """
#         run ansible palybook
#         """
#         try:
#             self.callback = ResultsCollector()
#             filenames = [playbookfile]  # playbook的路径
#             print('ymal file path:%s' % filenames)
#
#             extra_vars = playbookval  # 额外的参数 sudoers.yml以及模板中的参数，它对应ansible-playbook test.yml --extra-vars "host='aa' name='cc' "
#             extra_vars['host'] = hosts
#             self.variable_manager.extra_vars = extra_vars
#             print('playbook 额外参数:%s' % self.variable_manager.extra_vars)
#             # print(self.options._replace(tags=playbooktag))
#             self.options = self.options._replace(tags=playbooktag)
#             executor = PlaybookExecutor(
#                 playbooks=filenames, inventory=self.inventory, variable_manager=self.variable_manager,
#                 loader=self.loader,
#                 options=self.options, passwords=self.passwords,
#             )
#             executor._tqm._stdout_callback = self.callback
#             executor.run()
#         except Exception as e:
#             print("run_playbook:%s" % e)
#
#     def get_result(self):
#         self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
#         success_list = ['cmd', 'stdout', 'stderr', 'stdout_lines', 'stderr_lines', 'delta']
#         for host, result in self.callback.host_ok.items():
#             # success_json = {}
#             # for i in success_list:
#             #    success_json[i] = result._result[i]
#             self.results_raw['success'][host] = result._result
#
#         for host, result in self.callback.host_failed.items():
#             self.results_raw['failed'][host] = result._result['stderr']
#
#         for host, result in self.callback.host_unreachable.items():
#             self.results_raw['unreachable'][host] = result._result['msg']
#
#         print("Ansible执行结果集:%s" % json.dumps(self.results_raw, indent=4))
#         return json.dumps(self.results_raw, indent=4), self.results_raw
#
# if __name__ == '__main__':
#    res ={
#        "app": {
#            "hosts": [
#                {
#                    'username': 'root',
#                    'hostname': '120.55.115.101',
#                    'ip': '120.55.115.101',
#                    'ssh_key': '/usr/local/python36/django/key/localb',
#                    'port': 22
#                }
#            ]
#        },
#        "one": {
#            "hosts": [
#                {
#                    'username': 'root',
#                    'hostname': '121.41.77.69',
#                    'ip': '121.41.77.69',
#                    'ssh_key': '/usr/local/python36/django/key/localb',
#                    'password': 'pp-0p-0', #密钥 的密码无法认证
#                    'port': 22
#                },
#                {
#                    'username': 'root',
#                    'hostname': '120.55.115.101',
#                    'ip': '120.55.115.101',
#                    'ssh_key': '/usr/local/python36/django/key/localb',
#                    'password': 'pp-0p-0', #密钥 的密码无法认证
#                    'port': 22
#                }
#            ]
#        }
#    }
#    rapi = MyRunner(res)
#    rapi.run('one', 'shell', 'echo "1" > /root/txt')
#    #rapi.run_playbook('one', '/usr/local/python36/django/test.yml', {'host':'one','user':'root'})
#    #rapi.run_rule('one','/etc/ansible/site.yml', ['filebeat'], {'user':'root'})
#    r_data, b_data = rapi.get_result()
#    if b_data["success"] != {}:
#        print(b_data)
